<?php

namespace App\Services\Finance\Report;

use App\Models\Finance\Cost;
use App\Models\Finance\Income;
use App\Models\Finance\IncomeExcel;

use App\Models\Finance\Monthstatis;
use App\Models\Finance\Repair;
use Illuminate\Support\Facades\DB;
use App\Models\Agent\Agent;
use App\Models\User\UsersInfo;
use App\Models\Finance\Report;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Collection;

class ReportLogic
{
    public function accountStatement($data)
    {
        //$type=2指定人分账重新算账
        $type = $data['type'] ?? 0;
        $phone = $data['phone'] ?? '';
        $time = explode("-", $data['time']);
        //获取总成本
        $costCountMoney = $this->costCountMoney($data);
        //所有平台收入
        $spCountMoney = Income::where([['year', '=', $time[0]], ['month', '=', intval($time[1])]])->sum('amount');
        //每个月所有sp平台
        $spIncome = Income::where([['year', '=', $time[0]], ['month', '=', intval($time[1])]])->where('status','=',0)->select('platform_id')->distinct()->get()->toArray();
        if(!empty($spIncome)){
            foreach($spIncome as $v){
                //平台的总收入
                $spMoney = Income::where('platform_id','=',$v['platform_id'])->where([['year', '=', $time[0]], ['month', '=', intval($time[1])]])->sum('amount');
                //平台占比
                $spScale = round($spMoney/$spCountMoney,2);
                //平台应付成本
                $spPayMoney = round($spScale*$costCountMoney,2);
                //平台下的所有类型
                $incomeSpType = Income::where([['year', '=', $time[0]], ['month', '=', intval($time[1])]])->where('platform_id','=',$v['platform_id'])->get()->toArray();

                foreach ($incomeSpType as $t) {
                    if ($t['amount'] != 0) {
                        //平台类型的占比
                        $spTypeScale = round($t['amount']/$spMoney,2);
                        //平台类型的应付成本
                        $spTypePayMoney = round($spTypeScale*$spPayMoney,2);
                        //平台类型的总播放量
                        $spTypeCount = IncomeExcel::where('income_id','=',$t['id'])->sum('play');
                        //平台类型的所有歌曲数组
                        $incomeExcel = IncomeExcel::where('income_id','=',$t['id'])->where('status','=',$type)->get()->toArray();
                        foreach($incomeExcel as $v){
                            //当前这首歌应付的成本钱
                            $musicPayMoney = ($v['play']/$spTypeCount)*$spTypePayMoney;
                            //表演者的钱
                            $performerMoney = round(($t['amount']*(($v['play']/$spTypeCount)/2)-$musicPayMoney)*0.92,2);
                            //词作者的钱
                            $writerMoney = round(($t['amount']*(($v['play']/$spTypeCount)/2)-$musicPayMoney)*0.04*$v['writer_scale'],2);
                            //曲作者的钱
                            $composerMoney = round(($t['amount']*(($v['play']/$spTypeCount)/2)-$musicPayMoney)*0.04*$v['composer_scale'],2);
                            //当前这首歌的收入
                            $musicGetMoney =$performerMoney+$writerMoney+$composerMoney;
                            //计算代理收入的时候用到
                            $agentGetMoney = round($t['amount']*(($v['play']/$spTypeCount)/2),2);
                            //修改所有表的数据
                            if(empty($phone) && ($type==0 || $type==1)){
                                $updateRes = $this->updateAllTable($performerMoney,$writerMoney,$composerMoney,$musicGetMoney,$agentGetMoney,$v['id']);
                            }elseif(!empty($phone) || $type==2){
                                $updateRes = $this->updatePrivateTable($performerMoney,$writerMoney,$composerMoney,$musicGetMoney,$agentGetMoney,$v['id'],$time,$phone,$musicPayMoney,$type);
                            }
                            if($updateRes!=200){
                                return auto_failure('操作失败',$updateRes);
                            }
                        }
                    }
                }
            }
            //算出这个月的统计
            return $this->makeMonthStatis($time,$spCountMoney,$costCountMoney,$data['time'],$phone,$type);
        }else{
            return auto_failure('此月已结算','此月已结算');
        }
    }
    //普通结算
    public function updateAllTable($performerMoney,$writerMoney,$composerMoney,$musicGetMoney,$agentGetMoney,$incomeExcelId){
        //获取此歌用户及代理
        $v = DB::table('income_excel')->join('music', function ($join) {
            $join->on('income_excel.title', '=', 'music.title')->on('income_excel.album', '=', 'music.album');
        })->join('users_info', 'music.user_id', '=', 'users_info.id')->join('agent', 'users_info.software_id', '=', 'agent.software_id')->select('income_excel.title', 'music.title', 'income_excel.album', 'music.album', 'music.user_id', 'income_excel.id', 'income_excel.play', 'users_info.software_id', 'agent.id as agent_id','agent.scale')->where('income_excel.id','=',$incomeExcelId)->first();
        if(!empty($v)){
            DB::beginTransaction();
            try{
                IncomeExcel::where('id', '=', $incomeExcelId)->update(['user_id' => $v->user_id, 'agent_id' => $v->agent_id, 'status' => 1, 'money' => $musicGetMoney,'agent_money'=>($agentGetMoney * ($v->scale)/10),'performer_money'=>$performerMoney,'writer_money'=>$writerMoney,'composer_money'=>$composerMoney]);
                DB::commit();
            }catch (\Exception $e){
                DB::rollBack();
                return $e->getMessage();
            }
        }
        return 200;
    }
    //计算指定人
    public function updatePrivateTable($performerMoney,$writerMoney,$composerMoney,$musicGetMoney,$agentGetMoney,$incomeExcelId,$time,$phone,$musicPayMoney,$type){
        //获取此歌用户及代理
        if($type==2){
            DB::beginTransaction();
            try{
                $res = IncomeExcel::with('agent','user')->where('id','=',$incomeExcelId)->first()->toArray();
                IncomeExcel::where('id', '=', $incomeExcelId)->update(['money' => $musicGetMoney,'agent_money'=>($agentGetMoney * ($res['agent']['scale'])/10),'performer_money'=>$performerMoney,'writer_money'=>$writerMoney,'composer_money'=>$composerMoney]);
                $costData['amount'] = -$musicPayMoney;
                $costData['updated_at'] = date('Y-m-d H:i:s');
                Cost::where('user_id','=',$res['user']['id'])->update($costData);
                DB::commit();
            }catch (\Exception $e){
                DB::rollBack();
                return $e->getMessage();
            }
        }else {
            $v = DB::table('income_excel')->join('music', function ($join) {
                $join->on('income_excel.title', '=', 'music.title')->on('income_excel.album', '=', 'music.album');
            })->join('users_info', 'music.user_id', '=', 'users_info.id')->join('agent', 'users_info.software_id', '=', 'agent.software_id')->select('income_excel.title', 'music.title', 'income_excel.album', 'music.album', 'music.user_id', 'income_excel.id', 'income_excel.play', 'users_info.software_id', 'agent.id as agent_id','agent.scale','users_info.phone','users_info.real_name')->where('income_excel.status', '=', 0)->where('income_excel.id','=',$incomeExcelId)->where('users_info.phone','=',$phone)->first();
            if (!empty($v)) {
                DB::beginTransaction();
                try {
                    IncomeExcel::where('id', '=', $incomeExcelId)->update(['user_id' => $v->user_id, 'agent_id' => $v->agent_id, 'status' => 2, 'money' => $musicGetMoney, 'agent_money' => ($agentGetMoney * ($v->scale) / 10),'performer_money'=>$performerMoney,'writer_money'=>$writerMoney,'composer_money'=>$composerMoney]);
                    $time = implode('-', $time);
                    $costData['type'] = 1;
                    $costData['user_id'] = $v->user_id;
                    $costData['amount'] = -$musicPayMoney;
                    $costData['remark'] = $v->real_name . '(' . $time . ')指定人所占成本';
                    $costData['date'] = $time . '-00 00:00:00';
                    $costData['created_at'] = date('Y-m-d H:i:s');
                    $costData['updated_at'] = date('Y-m-d H:i:s');
                    Cost::insert($costData);
                    DB::commit();
                } catch (\Exception $e) {
                    DB::rollBack();
                    return $e->getMessage();
                }
            }
        }
        return 200;
    }

    public function costCountMoney($data){
        $time = explode("-", $data['time']);
        $cost = DB::select("select sum(amount) total from cost where year(date) = $time[0] and month(date)=$time[1]");
        $repair = Repair::where('time','=',$data['time'])->get();
        if(!empty($repair)) {
            $repair = $repair->toArray();
            $rmoney = 0;
            foreach ($repair as $v) {
                if($v['status'] ==0){
                    $rmoney +=$v['money'];
                }else{
                    $rmoney -=$v['money'];
                }
            }
        }
        $costCountMoney = $cost[0]->total+$rmoney;
        return $costCountMoney;
    }
    //插入月统计报表数据
    public function makeMonthStatis($time,$spCountMoney,$costCountMoney,$monthTime,$phone,$type){
        $month = Monthstatis::where('time','=',$monthTime)->get()->toArray();
        $monthIncomeID = Income::where([['year', '=', $time[0]], ['month', '=', intval($time[1])]])->select('id')->get()->toArray();
        foreach($monthIncomeID as $v){
            $id[] = $v['id'];
        }
        if($type==0 || $type==1){
            if(empty($phone) && empty($month)){
                $monthData['music_total'] = IncomeExcel::whereIn('income_id',$id)->where('status','=',1)->sum('money');
                $monthData['agent_total'] = IncomeExcel::whereIn('income_id',$id)->where('status','=',1)->sum('agent_money');
                $monthData['sp_total'] = $spCountMoney;
                $monthData['cost_total'] = $costCountMoney;
                $monthData['time'] = $monthTime;
                $monthData['created_at'] = date('Y-m-d H:i:s');
                $monthData['check_man1'] = session('username');
                $res = Monthstatis::insert($monthData);
            }elseif (!empty($month)){
                $monthData['music_total'] = IncomeExcel::whereIn('income_id',$id)->where('status','=',1)->sum('money');
                $monthData['agent_total'] = IncomeExcel::whereIn('income_id',$id)->where('status','=',1)->sum('agent_money');
                $monthData['sp_total'] = $spCountMoney;
                $monthData['cost_total'] = $costCountMoney;
                $monthData['time'] = $monthTime;
                $monthData['created_at'] = date('Y-m-d H:i:s');
                $monthData['music_status'] = 0;
                $res = Monthstatis::where('time','=',$monthTime)->update($monthData);
            }elseif (!empty($phone)){
                $monthData['appoint_total'] = IncomeExcel::whereIn('income_id',$id)->where('status','=',2)->sum('money');
                $monthData['cost_total'] = $costCountMoney;
                $monthData['time'] = $monthTime;
                $monthData['created_at'] = date('Y-m-d H:i:s');
                $monthData['check_man1'] = session('username');
                $res = Monthstatis::insert($monthData);
            }
        }elseif($type==2){
            $monthData['appoint_total'] = IncomeExcel::whereIn('income_id',$id)->where('status','=',2)->sum('money');
            $monthData['cost_total'] = $costCountMoney;
            $monthData['appoint_status'] = 0;
            $res = Monthstatis::where('time','=',$monthTime)->update($monthData);
        }
        if($res){
            return auto_success($res,'计算完毕');
        }else{
            return auto_failure('计算失败');
        }
    }

    // 复审列表
    public function accountsList(){
        $res = Report::orderBy('created_at','desc')->paginate(10);
        return auto_return($res,'成功！');
    }


    //搜索音乐人，代理，指定人信息
    public function typeSearch($data)
    {
        $time = explode("-", $data['time']);
        $monthIncomeID = Income::where([['year', '=', $time[0]], ['month', '=', intval($time[1])]])->select('id')->get()->toArray();
        foreach ($monthIncomeID as $v) {
            $id[] = $v['id'];
        }
        if ($data['type'] == 1) {
            $res = IncomeExcel::with('user')->selectRaw('user_id, sum(money) as countMoney')->whereIn('income_id', $id)->where('status', '=', 1)->groupBy('user_id')->get()->toArray();
        }
        if ($data['type'] == 2) {
            $res = IncomeExcel::with('agent')->selectRaw('agent_id, sum(agent_money) as countMoney')->whereIn('income_id', $id)->where('status', '=', 1)->groupBy('agent_id')->get()->toArray();
        }
        if ($data['type'] == 3) {
            $res = IncomeExcel::with('user')->selectRaw('user_id, sum(money) as countMoney')->whereIn('income_id', $id)->where('status', '=', 2)->groupBy('user_id')->get()->toArray();
        }
        return auto_success($res, '成功');
    }
    // 拒绝分账申请
    public function refuseApply($data)
    {
        $report = Report::find($data['id']);
        if ($data['type'] == 1) {
            $report->music_reason = $data['music_reason'];
            $report->music_status = 2;
        }
        if ($data['type'] == 2) {
            $report->appoint_reason = $data['appoint_reason'];
            $report->appoint_status = 2;
        }
        $res = $report->save();

        if ($res) {
            return auto_return($res, '成功');
        }
        return auto_failure($res, '失败');
    }

    // 通过分账申请
    public function adoptApply($data)
    {
        $report = Report::find($data['id']);
        $data['time'] = $report->time;
        $report->check_man2 = session('username');
        if ($data['type'] == 1) {
            $report->music_status = 3;
            $report->agent_status = 3;
            $pass = $this->passCheck($data);
        }

        if ($data['type'] == 2) {
            $report->appoint_status = 3;
            $pass = $this->passPrivateCheck($data);
        }
        if($pass == 200){
            $res = $report->save();
        }
        if ($res) {
            return auto_return($res, '成功');
        }
        return auto_failure($res, '失败');
    }

    //财务通过审核
    public function passCheck($data){
        $time = explode("-", $data['time']);
        $monthIncomeID = Income::where([['year', '=', $time[0]], ['month', '=', intval($time[1])]])->select('id')->get()->toArray();
        foreach($monthIncomeID as $v){
            $id[] = $v['id'];
        }
        $IncomeExcel = IncomeExcel::whereIn('income_id',$id)->where('status','=',1)->get()->toArray();
        DB::beginTransaction();
        try {
            foreach ($IncomeExcel as $v) {
                UsersInfo::where('id', '=', $v['user_id'])->increment('money', $v['money']);
                if ($v['agent_id'] != 0) {
                    Agent::where('id', '=', $v['agent_id'])->increment('money', $v['agent_money']);
                }
            }
            Income::where([['year', '=', $time[0]], ['month', '=', intval($time[1])]])->update(['status' => 2]);
            IncomeExcel::whereIn('income_id', $id)->where('status', '=', 1)->update(['check_status' => 1]);
            DB::commit();
            return 200;
        }catch(\Exception $e){
            DB::rollback();
            return $e->getMessage();
        }
    }

    //财务通过指定人审核
    public function passPrivateCheck($data){
        $time = explode("-", $data['time']);
        $monthIncomeID = Income::where([['year', '=', $time[0]], ['month', '=', intval($time[1])]])->select('id')->get()->toArray();
        foreach($monthIncomeID as $v){
            $id[] = $v['id'];
        }
        $IncomeExcel = IncomeExcel::whereIn('income_id',$id)->where('status','=',2)->get()->toArray();
        DB::beginTransaction();
        try {
            foreach ($IncomeExcel as $v) {
                UsersInfo::where('id', '=', $v['user_id'])->increment('money', $v['money']);
                if ($v['agent_id'] != 0) {
                    Agent::where('id', '=', $v['agent_id'])->increment('money', $v['agent_money']);
                }
            }
            IncomeExcel::whereIn('income_id', $id)->where('status', '=', 2)->update(['check_status' => 1]);
            DB::commit();
            return 200;
        }catch(\Exception $e){
            DB::rollback();
            return $e->getMessage();
        }
    }

    // 获取音乐人分账明细
    public function examineBill($data)
    {
        $year = substr($data['time'], 0, 4);
        $month = substr($data['time'], 5, 2);
        $condition['year'] = $year;
        $condition['month'] = intval($month);

        $incomeList = Income::where($condition)->get()->toArray();

        $income_id_list = []; //income表 id列表

        foreach ($incomeList as $list) {
            $income_id_list[] = $list['id'];
        }

        $excelList = IncomeExcel::where([['check_status', '=', '0'], ['status', '<>', '2']])
            ->whereIn('income_id', $income_id_list)->get()->toArray(); // 获取作品总数量

        $excelSum = IncomeExcel::where([['check_status', '=', '0'], ['status', '<>', '2']])
            ->whereIn('income_id', $income_id_list)->sum('money'); // 统计作品总收入

        $excel_user_id_list = []; //income表 user_id列表

        foreach ($excelList as $list) {
            $excel_user_id_list[] = $list['user_id'];
        }

        $excel_user_id_list = array_values(array_unique($excel_user_id_list)); // 去重并重新排序

        $user_num = count($excel_user_id_list); //统计用户数量;

        $userList = UsersInfo::whereIn('id', $excel_user_id_list)->get()->toArray(); //需要展示的用户列表

        $incomeExcelList = IncomeExcel::with('income', 'income.platform')
            ->whereHas('income', function ($query) use($condition) {
            $query->where($condition);
        })->where([['check_status', '=', '0'], ['status', '<>', '2']])
            ->whereIn('user_id', $excel_user_id_list)->get()->toArray(); // 获取作品对应的平台
        // 数组组合
        for ($i = 0; $i < count($userList); $i++) {
            $userList[$i]['gross_income'] = 0;
            for ($j = 0; $j < count($incomeExcelList); $j++) {
                if ($userList[$i]['id'] == $incomeExcelList[$j]['user_id']) {
                    $userList[$i]['excel'][] = $incomeExcelList[$j];
                    $userList[$i]['gross_income'] = bcadd($incomeExcelList[$j]['money'], $userList[$i]['gross_income'], 2);
                }
            }
        }

        // 获取当前的分页数，就是第6这样的
        $currentPage = LengthAwarePaginator::resolveCurrentPage();
        // 实例化collect方法
        $collection = new Collection($userList);
        // 定义一下每页显示多少个数据
        $perPage = 5;
        // 获取当前需要显示的数据列表
        $currentPageSearchResults = $collection->slice(($currentPage - 1) * $perPage, $perPage)->all();
        // 创建一个新的分页方法
        $paginatedSearchResults= new LengthAwarePaginator($currentPageSearchResults, count($collection), $perPage);
        // 设定分页跳转url
        $paginatedSearchResults = $paginatedSearchResults->setPath('/admin/examineBill/' . $data['time'] . '/music');

        return auto_return(['page' => $paginatedSearchResults, 'num' => $user_num, 'sum' => $excelSum], '成功');
    }

    // 获取代理分账明细
    public function agentExamineBill($data)
    {
        $year = substr($data['time'], 0, 4);
        $month = substr($data['time'], 5, 2);
        $condition['year'] = $year;
        $condition['month'] = intval($month);

        $incomeList = Income::where($condition)->get()->toArray();

        $income_id_list = []; //income表 id列表

        foreach ($incomeList as $list) {
            $income_id_list[] = $list['id'];
        }

        $excelList = IncomeExcel::where([['check_status', '=', '0'], ['status', '<>', '2']])
            ->whereIn('income_id', $income_id_list)->get()->toArray(); // 获取作品总数量

        $excelSum = IncomeExcel::where([['check_status', '=', '0'], ['status', '<>', '2']])
            ->whereIn('income_id', $income_id_list)->sum('agent_money'); // 统计作品总收入

        $excel_agent_id_list = []; //income表 agent_id列表

        foreach ($excelList as $list) {
            $excel_agent_id_list[] = $list['agent_id'];
        }

        $excel_agent_id_list = array_values(array_unique($excel_agent_id_list)); // 去重并重新排序

        $agent_num = count($excel_agent_id_list); //统计代理数量;

        $agentList = Agent::whereIn('id', $excel_agent_id_list)->get()->toArray(); //需要展示的代理列表

        $incomeExcelList = IncomeExcel::with('income', 'income.platform')
            ->whereHas('income', function ($query) use($condition) {
                $query->where($condition);
            })->where([['check_status', '=', '0'], ['status', '<>', '2']])
            ->whereIn('agent_id', $excel_agent_id_list)->get()->toArray(); // 获取作品对应的平台
        // 数组组合
        for ($i = 0; $i < count($agentList); $i++) {
            $agentList[$i]['gross_income'] = 0;
            for ($j = 0; $j < count($incomeExcelList); $j++) {
                if ($agentList[$i]['id'] == $incomeExcelList[$j]['agent_id']) {
                    $agentList[$i]['excel'][] = $incomeExcelList[$j];
                    $agentList[$i]['gross_income'] = bcadd($incomeExcelList[$j]['agent_money'], $agentList[$i]['gross_income'], 2);
                }
            }
        }

        // 获取当前的分页数，就是第6这样的
        $currentPage = LengthAwarePaginator::resolveCurrentPage();
        // 实例化collect方法
        $collection = new Collection($agentList);
        // 定义一下每页显示多少个数据
        $perPage = 5;
        // 获取当前需要显示的数据列表
        $currentPageSearchResults = $collection->slice(($currentPage - 1) * $perPage, $perPage)->all();
        // 创建一个新的分页方法
        $paginatedSearchResults= new LengthAwarePaginator($currentPageSearchResults, count($collection), $perPage);
        // 设定分页跳转url
        $paginatedSearchResults = $paginatedSearchResults->setPath('/admin/examineBill/' . $data['time'] . '/agent');

        return auto_return(['page' => $paginatedSearchResults, 'num' => $agent_num, 'sum' => $excelSum], '成功');
    }

    // 获取指定分账明细
    public function appointExamineBill($data)
    {
        $year = substr($data['time'], 0, 4);
        $month = substr($data['time'], 5, 2);
        $condition['year'] = $year;
        $condition['month'] = intval($month);

        $incomeList = Income::where($condition)->get()->toArray();

        $income_id_list = []; //income表 id列表

        foreach ($incomeList as $list) {
            $income_id_list[] = $list['id'];
        }

        $excelList = IncomeExcel::where([['check_status', '=', '0'], ['status', '=', '2']])
            ->whereIn('income_id', $income_id_list)->get()->toArray(); // 获取作品总数量

        $excelSum = IncomeExcel::where([['check_status', '=', '0'], ['status', '=', '2']])
            ->whereIn('income_id', $income_id_list)->sum('money'); // 统计作品总收入

        $excel_user_id_list = []; //income表 user_id列表

        foreach ($excelList as $list) {
            $excel_user_id_list[] = $list['user_id'];
        }

        $excel_user_id_list = array_values(array_unique($excel_user_id_list)); // 去重并重新排序

        $user_num = count($excel_user_id_list); //统计用户数量;

        $userList = UsersInfo::whereIn('id', $excel_user_id_list)->get()->toArray(); //需要展示的用户列表

        $incomeExcelList = IncomeExcel::with('income', 'income.platform')
            ->whereHas('income', function ($query) use($condition) {
                $query->where($condition);
            })->where([['check_status', '=', '0'], ['status', '=', '2']])
            ->whereIn('user_id', $excel_user_id_list)->get()->toArray(); // 获取作品对应的平台
        // 数组组合
        for ($i = 0; $i < count($userList); $i++) {
            $userList[$i]['gross_income'] = 0;
            for ($j = 0; $j < count($incomeExcelList); $j++) {
                if ($userList[$i]['id'] == $incomeExcelList[$j]['user_id']) {
                    $userList[$i]['excel'][] = $incomeExcelList[$j];
                    $userList[$i]['gross_income'] = bcadd($incomeExcelList[$j]['money'], $userList[$i]['gross_income'], 2);
                }
            }
        }

        // 获取当前的分页数，就是第6这样的
        $currentPage = LengthAwarePaginator::resolveCurrentPage();
        // 实例化collect方法
        $collection = new Collection($userList);
        // 定义一下每页显示多少个数据
        $perPage = 5;
        // 获取当前需要显示的数据列表
        $currentPageSearchResults = $collection->slice(($currentPage - 1) * $perPage, $perPage)->all();
        // 创建一个新的分页方法
        $paginatedSearchResults= new LengthAwarePaginator($currentPageSearchResults, count($collection), $perPage);
        // 设定分页跳转url
        $paginatedSearchResults = $paginatedSearchResults->setPath('/admin/examineBill/' . $data['time'] . '/appoint');

        return auto_return(['page' => $paginatedSearchResults, 'num' => $user_num, 'sum' => $excelSum], '成功');
    }

}